#include "ftcache.h"
#include "ftutils.h"

namespace TrueText {

FaceId::FaceId()
{ }

FaceIdManager::FaceIdManager()
{ }

FaceIdManager::~FaceIdManager()
{
	for (FaceIdMap::iterator i = this->faceIdMap.begin(); i != this->faceIdMap.end(); ++i)
		delete i->second;
	this->faceIdMap.clear();
}

FaceId* FaceIdManager::GetFaceId(std::string id, boost::function<FT_Face ()> faceLoader)
{
	FaceIdMap::iterator i = this->faceIdMap.find(id);
	if (i != this->faceIdMap.end())
		return i->second;

	std::auto_ptr<FaceId> fid(new FaceId());
	fid->id = id;
	fid->faceLoader = faceLoader;
	FaceId* result = this->faceIdMap[id] = fid.release();
	return result;
}

void FaceIdManager::RegisterStream(FT_Stream stream, boost::shared_ptr<Stream> ttStreamPtr)
{
	std::pair<StreamMap::const_iterator, bool> insertResult =
		this->streamMap.insert(std::make_pair(stream, ttStreamPtr));
	TT_ASSERT(insertResult.second);
}

void FaceIdManager::ClosingStream(FT_Stream stream)
{
	StreamMap::iterator i = this->streamMap.find(stream);
	if (i != this->streamMap.end())
	{
		this->streamMap.erase(i);
	}
	else
	{
		TT_FAIL_UNEXPECTED();
	}
}

namespace {
FT_Error FaceRequester(FTC_FaceID face_id,
	FT_Library library,
	FT_Pointer request_data,
	FT_Face* aface)
{
	FaceId* faceId = reinterpret_cast<FaceId*>(face_id);
	*aface = faceId->faceLoader();
	return FT_Err_Ok;
}

} // anonymous namespace

FaceIdManager* g_faceIdManager(0);
FTC_Manager g_ftcManager;
FTC_CMapCache g_cmapCache;
FTC_ImageCache g_imageCache;

void InitializeCache()
{
	g_faceIdManager = new FaceIdManager();
	FT_EH(FTC_Manager_New(GetLibraryHandle(),
		0,
		0,
		0,
		&FaceRequester,
		0,
		&g_ftcManager));
	FT_EH(FTC_CMapCache_New(g_ftcManager, &g_cmapCache));
	FT_EH(FTC_ImageCache_New(g_ftcManager, &g_imageCache));
}

void ShutdownCache()
{
	FTC_Manager_Done(g_ftcManager);
	delete g_faceIdManager;
	g_faceIdManager = 0;
}

FaceIdManager* GetFaceIdManager()
{
	return g_faceIdManager;
}

FTC_Manager GetFtcManager()
{
	return g_ftcManager;
}

FTC_CMapCache GetCMapCache()
{
	return g_cmapCache;
}

FTC_ImageCache GetImageCache()
{
	return g_imageCache;
}

} // namespace TrueText